package com.alks.function.service.impl.asyncImpl;

import com.alks.common.aop.RedisLock;
import com.alks.common.utils.BigDecimalUtil;
import com.alks.common.utils.beanutils.ObjectUtils;
import com.alks.entity.data.entity.*;
import com.alks.entity.data.enums.MtlEnum;
import com.alks.function.data.dto.finance.costcheck.PcVRecSlipCfmDto;
import com.alks.function.mapper.chengKong.PcLotHeadMapper;
import com.alks.function.mapper.finance.costcheck.PcLotCostMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;

@Slf4j
@Service
public class LotCostAsyncServiceImpl {

    @Autowired
    private PcLotCostMapper pcLotCostMapper;

    @Autowired
    private PcLotHeadMapper pcLotHeadMapper;

    @Async
    @Transactional
    @RedisLock(key = "key:InsertCalculation", expireTime = 60, message = "系统处理数据中,请稍后重试!")
    public void InsertCalculation(List<String> list){
        if (ObjectUtils.isEmpty(list)){
            //查询已完工指令但是没有封账的指令
            list = pcLotCostMapper.getLotNoByFlagToCost();;
        }
        //计算指令成本
        if (!ObjectUtils.isEmpty(list)){
            for (String t : list) {
                //删除明细
                pcLotCostMapper.delCostDetail(t);
                //删除主表明细
                pcLotCostMapper.delCostHead(t);
                //查询订单数量
                LambdaQueryWrapper<PcLotHead> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(PcLotHead::getLotNo,t);
                PcLotHead pcLotHead = pcLotHeadMapper.selectOne(wrapper);
                BigDecimal orderQty = new BigDecimal(Float.toString(pcLotHead.getOrderQty()));
                BigDecimal orderQty2 = new BigDecimal(Float.toString(pcLotHead.getTotalQty()));
                BigDecimal stdUsage=BigDecimal.ZERO;
                BigDecimal price=BigDecimal.ZERO;
                BigDecimal price1=BigDecimal.ZERO;
                BigDecimal price3=BigDecimal.ZERO;
                BigDecimal amt=BigDecimal.ZERO;
                //查询指令用量明细
                List<PcLotUsage> pcLotUsageList = pcLotCostMapper.getPcLotUsageList(t);
                int i=1;
                if (!ObjectUtils.isEmpty(pcLotUsageList)) {
                    for (PcLotUsage rec : pcLotUsageList) {
                        if (!ObjectUtils.isEmpty(rec.getSize1())){
                            // 将 Float 转换为 BigDecimal 使用 String 转换，避免精度丢失
                            BigDecimal ttlUsage = new BigDecimal(Float.toString(rec.getTtlUsage()));
                            stdUsage = BigDecimalUtil.div(ttlUsage, orderQty, 5);
                        }else {
                            stdUsage=rec.getStdUsage()!=null?rec.getStdUsage():BigDecimal.ZERO;
                        }

                        //判断是否贴合材料
                        if (!rec.getMtlNo().startsWith("N")){
                            price = pcLotCostMapper.getPrice(t, rec.getMtlNo());
                        }else {
                            price1 = pcLotCostMapper.getPrice(t, rec.getMtlNo());
                            BigDecimal price2=BigDecimal.ZERO;
                            //查询贴合材料下子材料,查询BF公司下子材料
                            List<SdBomFitSub> bomFitList = pcLotCostMapper.getSdBomFitList(rec.getMtlNo(), pcLotHead.getCompanyId());
                            if (!ObjectUtils.isEmpty(bomFitList)){
                                for (SdBomFitSub rec2 : bomFitList) {
                                    price= pcLotCostMapper.getPrice(t, rec2.getSubMtlNo());
                                    price2=BigDecimalUtil.add(price2, BigDecimalUtil.mul(price, rec2.getPercent()!=null?rec2.getPercent():BigDecimal.ZERO));
                                }
                            }
                            price=BigDecimalUtil.add(price1, price2);
                        }
                        //保留计算的价格
                        price3 = price;
                        //如果这个单价为空或者等于0查询替代的价格
                        if (price==null||price.compareTo(BigDecimal.ZERO) == 0){
                            LocalDate date=null;
                            String slipNo=null;
                            //查询当前材料最大时间和单号
                            PcDrawDetail slipDateAndSlipNo = pcLotCostMapper.getSlipDateAndSlipNo(t, rec.getMtlNo());
                            if (slipDateAndSlipNo!=null){
                                date=slipDateAndSlipNo.getSlipDate();
                                slipNo=slipDateAndSlipNo.getSlipNo();
                            }
                            //查询替代的编码
                            String mtlNo = pcLotCostMapper.getPcDrawReplace(rec.getMtlNo(), slipNo);
                            if (ObjectUtils.isEmpty(mtlNo)){
                                mtlNo= rec.getMtlNo();
                            }
                            //根据替换的编码查询价格
                             price = pcLotCostMapper.getPrice(t, mtlNo);
                            if (price==null||price.compareTo(BigDecimal.ZERO) == 0){
                                //根据日期查
                                price=pcLotCostMapper.getPriceByDate(mtlNo,date);
                                if (price==null||price.compareTo(BigDecimal.ZERO)==0){
                                    //查询最大送货日期
                                    price=pcLotCostMapper.getPriceByMtlNo(mtlNo);
                                }
                            }
                        }
                        FrLotCostDetail detail = new FrLotCostDetail();
                        detail.setLotNo(t);
                        detail.setMtlType(MtlEnum.TYPE_UPPER.getValue());
                        detail.setSeqNo(BigDecimal.valueOf(i));
                        detail.setPartName(rec.getPartName());
                        detail.setMtlNo(rec.getMtlNo());
                        detail.setMltName(rec.getMtlColor()+rec.getMtlName());
                        detail.setMltSpec(rec.getMtlSpec());
                        detail.setMltUnit(rec.getMtlUnit());
                        detail.setStdUsage(stdUsage);
                        detail.setPrice(price);
                        detail.setPrice2(price3);
                        i++;
                        pcLotCostMapper.addFrLotCostDetail(detail);
                    }
                }
                pcLotCostMapper.updateFrLotCostDetailByAmt(t,MtlEnum.TYPE_UPPER.getValue());

                //处理多购数据
                i=1;
                List<PcVRecSlipCfmDto> vList = pcLotCostMapper.getVList(t);
                if (!ObjectUtils.isEmpty(vList)){
                    for (PcVRecSlipCfmDto rec : vList) {
                        FrLotCostDetail detail = new FrLotCostDetail();
                        detail.setLotNo(t);
                        detail.setMtlType(MtlEnum.TYPE_UPPER2.getValue());
                        detail.setSeqNo(BigDecimal.valueOf(i));
                        detail.setPartName("多购");
                        detail.setMtlNo(rec.getMtlNo());
                        detail.setMltName(rec.getMtlName());
                        detail.setMltSpec(rec.getMtlSpec());
                        detail.setMltUnit(rec.getMtlUnit());
                        detail.setStdUsage(BigDecimalUtil.div(rec.getQty(),orderQty2,5));
                        detail.setPrice(rec.getPrice());
                        detail.setAmt(BigDecimalUtil.div(rec.getAmt(),orderQty2,2));
                        i++;
                        pcLotCostMapper.addFrLotCostDetail(detail);
                    }
                }

                //处理包材数据
                i=1;
                List<PcPackDetail> packDetailList = pcLotCostMapper.getPcPackDetailList(t);
                if (!ObjectUtils.isEmpty(packDetailList)){
                    for (PcPackDetail rec : packDetailList) {
                        //查询包材最大单价
                        price= pcLotCostMapper.getPrice2(t, rec.getMtlNo());
                        amt=BigDecimalUtil.mul(BigDecimalUtil.div(rec.getTtlUsage(),orderQty,5),price,2);
                        FrLotCostDetail detail = new FrLotCostDetail();
                        detail.setLotNo(t);
                        detail.setMtlType(MtlEnum.TYPE_PACK.getValue());
                        detail.setSeqNo(BigDecimal.valueOf(i));
                        detail.setPartName(rec.getTypeName());
                        detail.setMtlNo(rec.getMtlNo());
                        detail.setMltName(rec.getMtlName());
                        detail.setMltSpec(rec.getMtlSpec());
                        detail.setMltUnit(rec.getMtlUnit());
                        detail.setStdUsage(BigDecimalUtil.div(rec.getTtlUsage(),orderQty,5));
                        detail.setPrice(price);
                        detail.setAmt(amt);
                        i++;
                        pcLotCostMapper.addFrLotCostDetail(detail);
                    }
                }

                //处理大底数据
                i=1;
                List<PcVRecSlipCfmDto> soleDetailList = pcLotCostMapper.getVList2(t,"大底");
                if (!ObjectUtils.isEmpty(soleDetailList)){
                    for (PcVRecSlipCfmDto rec : soleDetailList) {
                        FrLotCostDetail detail = new FrLotCostDetail();
                        detail.setLotNo(t);
                        detail.setMtlType(MtlEnum.TYPE_SOLE.getValue());
                        detail.setSeqNo(BigDecimal.valueOf(i));
                        detail.setPartName("大底");
                        detail.setMtlNo(rec.getMtlNo());
                        detail.setMltName(rec.getMtlName());
                        detail.setMltSpec(rec.getMtlSpec());
                        detail.setMltUnit(rec.getMtlUnit());
                        detail.setStdUsage(BigDecimalUtil.div(rec.getQty(),orderQty,5));
                        detail.setPrice(rec.getPrice());
                        detail.setAmt(BigDecimalUtil.div(rec.getAmt(),orderQty,2));
                        i++;
                        pcLotCostMapper.addFrLotCostDetail(detail);

                    }
                }

                //处理面衬数据
                i=1;
                List<PcVRecSlipCfmDto> faceDetailList = pcLotCostMapper.getVList2(t,"面衬");
                if (!ObjectUtils.isEmpty(faceDetailList)){
                    for (PcVRecSlipCfmDto rec : faceDetailList) {
                        FrLotCostDetail detail = new FrLotCostDetail();
                        detail.setLotNo(t);
                        detail.setMtlType(MtlEnum.TYPE_SOLE.getValue());
                        detail.setSeqNo(BigDecimal.valueOf(i));
                        detail.setPartName("面衬");
                        detail.setMtlNo(rec.getMtlNo());
                        detail.setMltName(rec.getMtlName());
                        detail.setMltSpec(rec.getMtlSpec());
                        detail.setMltUnit(rec.getMtlUnit());
                        detail.setStdUsage(BigDecimalUtil.div(rec.getQty(),orderQty,5));
                        detail.setPrice(rec.getPrice());
                        detail.setAmt(BigDecimalUtil.div(rec.getAmt(),orderQty,2));
                        i++;
                        pcLotCostMapper.addFrLotCostDetail(detail);
                    }
                }
                //统计汇总金额
                BigDecimal m1 = pcLotCostMapper.getLotDetailSum(t, "U",0);
                BigDecimal m11 = pcLotCostMapper.getLotDetailSum2(t, "U");
                BigDecimal m12 = pcLotCostMapper.getLotDetailSum3(t, "U2");
                BigDecimal m2 = pcLotCostMapper.getLotDetailSum(t, "P",0);
                BigDecimal m3 = pcLotCostMapper.getLotDetailSum(t, "S",1);
                BigDecimal m4 = pcLotCostMapper.getLotDetailSum(t, "S",2);

                //统计冲裁数据
                BigDecimal l1 = pcLotCostMapper.getLotDetailSum4(t);
                //统计手工数据
                BigDecimal l2 = pcLotCostMapper.getLotDetailSum5(t);
                //统计外发数据
                BigDecimal l3 = pcLotCostMapper.getLotDetailSum6(t);
                //统计针车数据
                BigDecimal l4 = pcLotCostMapper.getLotDetailSum7(t);
                //统计补料数据
                BigDecimal f1 = pcLotCostMapper.getLotDetailSum8(t,orderQty);
                BigDecimal f12 = pcLotCostMapper.getLotDetailSum9(t,orderQty);
                BigDecimal f2 = pcLotCostMapper.getLotDetailSum10(t,orderQty);

                StringBuilder status = new StringBuilder();
                if (m1 == null) status.append("/缺面材");
                if (m2 == null) status.append("/缺包材");
                if (m3 == null) status.append("/缺底材");
                if (l1 == null) status.append("/缺冲裁");
                if (l2 == null) status.append("/缺手工");
                if (l3 == null) status.append("/缺外协");
                if (l4 == null) status.append("/缺针车");
                if (status.length() == 0) {
                    status= new StringBuilder("OK");
                } else {
                    status = new StringBuilder(status.toString().substring(1));
                }
                FrLotCostHead costHead = new FrLotCostHead();
                costHead.setLotNo(t);
                costHead.setUpperMtl(m1!=null?m1:BigDecimal.ZERO);
                costHead.setUpperMtl2(BigDecimalUtil.add(m11, m12));
                costHead.setPackMtl(m2);
                costHead.setSoleMtl(m3);
                costHead.setSoleMtl2(m4);
                costHead.setCutLabor(l1);
                costHead.setProcessLabor(l2);
                costHead.setOutLabor(l3);
                costHead.setStitchLabor(l4);
                costHead.setSupplementFee(f1);
                costHead.setSupplementFee2(f12);
                costHead.setOtherFee(f2);
                costHead.setStatus(status.toString());
                costHead.setAdminFee(BigDecimal.valueOf(10));
                costHead.setPowerFee(BigDecimal.valueOf(1));
                costHead.setLastLabor(BigDecimal.valueOf(12));
                pcLotCostMapper.addFrLotCostHead(costHead);
                pcLotCostMapper.updateFrLotCostHead(t);
                pcLotCostMapper.updatePcCostLot(t);
            }
        }
    }

}
